package com.tcm.order.service.impl;

import com.base.core.utils.R;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.tcm.order.domain.dto.OrderDTO;
import com.tcm.order.service.DelayQueueService;
import com.tcm.order.service.OrderService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.annotation.StreamListener;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

@Service
@EnableBinding({DelayQueueSource.class, DelayQueueSink.class})
public class DelayQueueServiceImpl implements DelayQueueService {

    @Resource
    private OrderService orderService;

    @Resource
    private DelayQueueSource source;

    private final static Logger log = LoggerFactory.getLogger(DelayQueueServiceImpl.class);

    @Override
    public void send(OrderDTO orderDTO, long delay) {
        Message<OrderDTO> message = MessageBuilder.withPayload(orderDTO)
                .setHeader("x-delay", delay).build();
        source.output().send(message);
        log.info("发布延迟队列消息，OrderId: " + orderDTO.getId());
    }

    @Override
    @StreamListener(DelayQueueSink.INPUT)
    public void receive(String message) {
        ObjectMapper om = new ObjectMapper();
        OrderDTO orderDTO = null;

        try {
            orderDTO = om.readValue(message, OrderDTO.class);
        } catch (JsonProcessingException e) {
            R.throwFail("生成订单信息失败，OrderId: " + orderDTO.getId());
        }

        log.info("订单超时未支付，OrderId: " + orderDTO.getId());
        try {
            if (orderService.cancel(orderDTO.getUserId(), orderDTO.getId()) != 1) {
                R.throwFail("保存订单信息失败，OrderId:" + orderDTO.getId());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
